package com.easy.frame.servers.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easy.frame.base.api.pojo.BasePO;
import com.easy.frame.base.api.pojo.PageDTO;
import com.easy.frame.base.api.pojo.PageVO;
import com.easy.frame.base.basic.constant.DbConstants;
import com.easy.frame.base.basic.constant.NumberConstants;
import com.easy.frame.base.basic.enums.DictCodeEnum;
import com.easy.frame.base.basic.exception.ServiceException;
import com.easy.frame.base.basic.util.AuthUtil;
import com.easy.frame.base.service.mp.page.PageProxy;
import com.easy.frame.servers.sys.dto.SysProjectDTO;
import com.easy.frame.servers.sys.dto.SysTenantAddDTO;
import com.easy.frame.servers.sys.dto.SysTenantPageDTO;
import com.easy.frame.servers.sys.dto.SysTenantUpdateDTO;
import com.easy.frame.servers.sys.entity.SysBusinessType;
import com.easy.frame.servers.sys.entity.SysTenant;
import com.easy.frame.servers.sys.entity.SysTenantDetail;
import com.easy.frame.servers.sys.mapper.project.SysProjectMapper;
import com.easy.frame.servers.sys.mapper.tenant.SysTenantDetailMapper;
import com.easy.frame.servers.sys.mapper.tenant.SysTenantMapper;
import com.easy.frame.servers.sys.service.SysBusinessTypeService;
import com.easy.frame.servers.sys.service.SysDictService;
import com.easy.frame.servers.sys.service.SysTenantService;
import com.easy.frame.servers.sys.vo.SysProjectVO;
import com.easy.frame.servers.sys.vo.SysTenantDetailVO;
import com.easy.frame.servers.sys.vo.SysTenantVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 系统租户表 服务实现类
 *
 * @author zzf
 * @since 2020-12-14
 */
@Service
public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant> implements SysTenantService {

    @Resource
    private SysTenantDetailMapper detailMapper;

    @Resource
    private SysProjectMapper sysProjectMapper;

    @Autowired
    SysBusinessTypeService sysBusinessTypeService;

    @Autowired
    SysTenantService sysTenantService;

    @Autowired
    SysDictService sysDictService;

    @Override
    public PageVO<SysTenantVO> selectForPage(PageDTO<SysTenantPageDTO> pageDTO) {
        if (StrUtil.isEmpty(pageDTO.getSortName()) && StrUtil.isEmpty(pageDTO.getSortOrder())) {
            pageDTO.setSortName("st.update_time");
            pageDTO.setSortOrder("desc");
        }
        PageVO<SysTenantVO> proxy = PageProxy.proxy(baseMapper::selectForPage, pageDTO);
        List<SysTenantVO> records = proxy.getRecords();
        records.forEach(s->{
            StringBuilder sb = new StringBuilder();
            List<Integer> type = s.getType();
            s.getType().forEach(x ->{
                String name = sysDictService.getName(DictCodeEnum.ORG_TYPE.getCode(), x);
                sb.append(sysDictService.getName(DictCodeEnum.ORG_TYPE.getCode(),x)).append(",");
            });
            if (sb.length() > 0) {
                s.setTypeName(sb.substring(0, sb.length()-1));
            }
        });
        return proxy;
    }

    @Override
    public SysTenant selectById(Long id) {
        return baseMapper.selectById(id);
    }

    /**
     * 新增
     * 1.校验只能存在1个系统管理方，无论租户是否有效
     * 2.校验编号唯一性，无论租户是否有效
     */
    @Override
    public void add(SysTenantAddDTO addDTO) {
        if (addDTO.getSysAdmin().equals(DbConstants.DEFAULT_YES) && this.getSysAdminId() != null) {
            throw new ServiceException("已存在系统管理方，请确认后重新提交。");
        }
        if (this.checkCode(addDTO.getCode()) != null) {
            throw new ServiceException("编号已存在，请确认后重新提交。");
        }
        SysTenant sysTenant = this.dto2Tenant(addDTO);
        sysTenant.setCreateBy(AuthUtil.getCurrentUserId());
        sysTenant.setUpdateBy(AuthUtil.getCurrentUserId());
        sysTenant.setCreateTime(new Date());
        sysTenant.setUpdateTime(new Date());
        baseMapper.insert(sysTenant);
        detailMapper.insert(this.dto2Detail(addDTO, sysTenant.getId()));
    }

    @Override
    public void updateDetail(SysTenantUpdateDTO updateDTO) {
        SysTenant sysTenant = this.dto2Tenant(updateDTO);
        sysTenant.setUpdateBy(AuthUtil.getCurrentUserId());
        sysTenant.setUpdateTime(new Date());
        baseMapper.updateById(sysTenant);
        detailMapper.update(this.dto2Detail(updateDTO, updateDTO.getId()),
                new LambdaUpdateWrapper<SysTenantDetail>()
                        .eq(SysTenantDetail::getTenantId, updateDTO.getId()));
    }

    @Override
    public int updateDeleted(Long id) {
        SysTenant sysTenant = new SysTenant();
        sysTenant.setId(id);
        sysTenant.setDeleted(DbConstants.DEFAULT_YES);
        return baseMapper.updateById(sysTenant);
    }

    @Override
    public SysTenantVO selectVOById(Long id) {
        return baseMapper.selectVOById(id);
    }

    @Override
    public Long checkCode(String code) {
        SysTenant sysTenant = baseMapper.selectOne(new LambdaQueryWrapper<SysTenant>()
                .eq(SysTenant::getCode, code)
                .eq(BasePO::getDeleted, DbConstants.DEFAULT_NO));
        return sysTenant != null ? sysTenant.getId() : null;
    }

    @Override
    public Long getSysAdminId() {
        Long sysAdminId = baseMapper.selectSysAdminId();
        return sysAdminId != null && !sysAdminId.equals(NumberConstants.CONSTANTS_ZERO) ? sysAdminId : null;
    }

    @Override
    public SysTenantDetailVO getDetail(Long id) {
        return baseMapper.selectDetail(id);
    }

    @Override
    public List<SysTenant> selectAllTenant() {
        return baseMapper.selectTenantList();
    }

    @Override
    public PageVO<SysProjectVO> getProjectDetailPage(PageDTO<SysProjectDTO> pageDTO) {
        List<SysProjectVO> sysProjectVO = sysProjectMapper.selectProjectDetailForPage(pageDTO.getParam());
        sysProjectVO.forEach(s -> {
            List<SysBusinessType> list = sysBusinessTypeService.list(new LambdaQueryWrapper<SysBusinessType>()
                    .eq(SysBusinessType::getTenantId, pageDTO.getParam().getTenantId())
                    .eq(SysBusinessType::getIsAuth, DbConstants.DEFAULT_YES));
            StringBuilder sb = new StringBuilder();
            list.forEach(x -> {
                sb.append(x.getName()).append(",");
            });
            if(sb.length()>0){
                String string = sb.toString();
                s.setBusinessType(string.substring(0,sb.length()-1));
            }
        });
        PageVO<SysProjectVO> pageVO = new PageVO<>(pageDTO);
        pageVO.setRecords(sysProjectVO);
        return pageVO;
    }

    @Override
    public void updateBusinessById(SysBusinessType entity) {
        entity.setUpdateBy(AuthUtil.getCurrentUserId());
        entity.setUpdateTime(new Date());
        sysBusinessTypeService.updateById(entity);
        SysTenant sysTenant = new SysTenant();
        sysTenant.setId(entity.getTenantId());
        sysTenant.setAllAuth(0);
        baseMapper.updateById(sysTenant);
    }

    @Override
    public void updateAllBusinessById(Long tenantId) {
        List<SysBusinessType> sysBusinessTypeList = sysBusinessTypeService.selectByTenantId(tenantId);
        sysBusinessTypeList.forEach(s -> {
            s.setIsAuth(1);
            s.setUpdateBy(AuthUtil.getCurrentUserId());
            s.setUpdateTime(new Date());
        });
        sysBusinessTypeService.updateBatchById(sysBusinessTypeList);
        SysTenant sysTenant = new SysTenant();
        sysTenant.setId(tenantId);
        sysTenant.setAllAuth(1);
        sysTenantService.updateById(sysTenant);
    }

    private SysTenant dto2Tenant(Object obj) {
        SysTenant sysTenant = new SysTenant();
        BeanUtil.copyProperties(obj, sysTenant);
        return sysTenant;
    }

    private SysTenantDetail dto2Detail(Object obj, Long tenantId) {
        SysTenantDetail detail = new SysTenantDetail();
        BeanUtil.copyProperties(obj, detail);
        detail.setTenantId(tenantId);
        return detail;
    }
}